import test from "../../../o1SceneBundles/hall/test/test";
import NormalLevelBase from "../../Game/Base/LevelBase";
import { GAME_EVENT, PAGE } from "../../Game/Enum";
import { IInGamePagePrams, INormalLevelStruct } from "../../Game/Interface";
import mainRoot from "../../Game/MainRoot";
import CardCompositionInGamePage from "../../Game/Page/CardCompositionInGamePage";
import CardIntroductionPage from "../../Game/Page/CardIntroductionPage";
import O1HD from "../../engines/gameEngine";
import { CsvFileKind } from "../../engines/libs/CsvFileKind";
import data_control from "../../engines/libs/data_control";
import CsvDataManage from "../../engines/managers/CsvDataManage";
import level_cardComposition_card from "./base/level_cardComposition_card";
import level_cardComposition_cardGroup from "./base/level_cardComposition_cardGroup";
import { level_cardCompositionCardType, level_cardCompositionE, level_cardCompositionGroupTypeE } from "./const/level_cardCompositionConst";

const {ccclass, property} = cc._decorator;

@ccclass
export default class level_cardComposition extends NormalLevelBase {

    @property({type:cc.Node,tooltip:"卡牌组Content"})
    groupContent:cc.Node = null;

    @property({type:cc.Node,tooltip:"卡牌Content"})
    cardContent:cc.Node = null;

    @property({type:cc.Prefab,tooltip:"卡片预制体"})
    cardP:cc.Prefab = null;

    @property({type:cc.Prefab,tooltip:"组预制体"})
    groupP:cc.Prefab = null;

    @property({type:cc.Node,tooltip:"点击节点"})
    touchNode:cc.Node = null;

    @property({type:cc.Node,tooltip:"彩带节点"})
    coloured:cc.Node = null;

    inGamePage:CardCompositionInGamePage = null;

    cardStrAry:string[] = [
        "A",
        "2",
        "3",
        "4",
        "5",
        "6",
        "7",
        "8",
        "9",
        "10",
        "J",
        "Q",
        "K",
    ];

    /**卡牌节点池 */
    cardPool:cc.NodePool = new cc.NodePool();

    /**游戏阶段数组 */
    phaseTargetAry:number[] = [];

    /**需要解锁的所有组 */
    needUnlockGroupAry:level_cardComposition_cardGroup[] = [];

    /**当前游戏阶段 */
    private curStep:number = -1;

    /**最大的卡牌 */
    maxCardNum:number = 0;

    /**创建的最小的卡牌 */
    createMinCardNum:number = 0;

    startCreateMaxCard:number = 0;

    /**当前点击的节点 */
    curSelectNode:cc.Node = null;

    /**是否可以点击 */
    canTouch:boolean = true;

    levelData:any = null;

    compositionCards:number[][] = [
        [2,6,10],
        [1,5,9],
        [3,7,11],
        [0,4,8,12]
    ]

    colorArys:cc.Color[][] = [
        [],
        [],
        [],
        []
    ]

    colorArysCopy:cc.Color[][] = [
        [cc.color(230,0,18),cc.color(255,97,0)],
        [cc.color(0,153,68),cc.color(0,158,150)],
        [cc.color(0,160,233),cc.color(29,32,136)],
        [cc.color(146,7,131),cc.color(229,0,79)],
    ]

    groupPos:cc.Vec2[] = [
        cc.v2(-280,5),
        cc.v2(-140,5),
        cc.v2(-0,5),
        cc.v2(140,5),
        cc.v2(280,5),
        cc.v2(-280,495),
        cc.v2(-140,495),
        cc.v2(-0,495),
        cc.v2(140,495),
        cc.v2(280,495),
    ]

    colorMap:{} = {};

    dealFlag:boolean = false;

    introductionStack:string[] = [];

    
    /**缓存的key */
    private save_data_key = "user-data-card-composition-save-key";

    _introductionAry:string[] = [];

    openIntroductionFlag:boolean = false;

    /**加载数据 */
    loadData(){
        let dataStr = O1HD.getServices().localStorageSrv.getStorage(this.save_data_key) || "[]";
        let data:string[] = JSON.parse(dataStr);
        this._introductionAry = data;
    }

    writeData(){
        O1HD.getServices().localStorageSrv.setStorage(this.save_data_key,JSON.stringify(this._introductionAry));
    }

    async Init(info: INormalLevelStruct): Promise<void> {
        this.loadData();
        this.levelInfo = info;
        this.m_mode = info.mode;
        this.tips = info.tips;
        // console.warn("关卡初始化", this.levelInfo);
        let inGamePrams: IInGamePagePrams = {
            mode: this.m_mode,
            levelInfo:this.levelInfo,
            title: info.title,
            tips: info.tips,
            hideTitle: info.hideTitle
        }
        O1HD.on(GAME_EVENT.ON_BTN_TIPS, this.OnTips.bind(this));
        this.levelData = O1HD.getManagers().csvDataManager.getCsvDataItem(CsvFileKind.CsvFile.cardCompositionLevel,this.levelInfo.level);
        let minCard:number = Number(this.levelData["min_card"]);
        let maxCard:number = Number(this.levelData["max_card"]);
        this.createMinCardNum = minCard;
        this.startCreateMaxCard = maxCard;
        O1HD.getManagers().soundMgr.loadSoundBundle("cardComposition");
        let phaseStr:string = this.levelData["phase_target"];
        this.phaseTargetAry = phaseStr.split("|").map((v:string)=>{
            return Number(v);
        });
        let cLength:number = level_cardCompositionE.LENGTH - 1;
        for(let i = 0; i < cLength; i++){
            let aryIndex:number = this.compositionCards.findIndex((v:number[])=>{
                return v.includes(i);
            });
            if(this.colorArys[aryIndex].length <= 0){
                this.colorArys[aryIndex] = data_control.randomSortArray(this.colorArysCopy[aryIndex].concat());
            }
            this.colorMap[i] = this.colorArys[aryIndex].pop();
        }
        this.initGroup();
        this.inGamePage = await mainRoot.UISystem.OpenPage(PAGE.CARD_COMPOSITION_INGAME_PAGE,inGamePrams) as CardCompositionInGamePage;
        this.inGamePage.bindLevel(this);
        this.createCards(true,false,false);
        this.touchNodeAddEvent();
        this.canTouch = true;
        this.dealFlag = true;
    }

    onLoad(){
        
    }

    start(){

    }

    /**初始化组 */
    initGroup(){
        let defaultGroup:number = Number(this.levelData["default_group"]);
        for(let i = 0;i<this.groupPos.length;i++){
            let group :cc.Node = cc.instantiate(this.groupP);
            group.setParent(this.groupContent);
            group.setPosition(this.groupPos[i]);
            let gs = group.getComponent(level_cardComposition_cardGroup);
            if(i<defaultGroup){
                gs.setGroupType(level_cardCompositionGroupTypeE.normal);
            }else if(i < defaultGroup + this.phaseTargetAry.length - 1){
                gs.setGroupType(level_cardCompositionGroupTypeE.unlock);
            }else{
                gs.setGroupType(level_cardCompositionGroupTypeE.temp);
            }
        }
        this.groupContent.children.forEach((group:cc.Node)=>{
            let gs = group.getComponent(level_cardComposition_cardGroup);
            gs.bindData(this);
            if(gs.groupType == level_cardCompositionGroupTypeE.unlock){
                gs.setTargetLb(`合成${this.cardStrAry[this.phaseTargetAry[this.needUnlockGroupAry.length]]}\n解锁`)
                this.needUnlockGroupAry.push(gs);
            }
        });
    }

    touchNodeAddEvent(){
        this.touchNode.on('touchend',this.onTouchEndTouchNode,this);
    }

    async onTouchEndTouchNode(e:cc.Event.EventTouch){
        if(!this.canTouch){
            return;
        }
        this.canTouch = false;
        let targetNode:cc.Node = null;
        this.groupContent.children.forEach((n:cc.Node)=>{
            let nBound = n.getBoundingBoxToWorld();
            if(nBound.contains(e.getLocation())){
                targetNode = n;
            }
        });
        if(!targetNode){
            if(this.curSelectNode){
                let cs = this.curSelectNode.getComponent(level_cardComposition_cardGroup);
                cs.setMoveCardSelect(false);
            }
            this.curSelectNode = null;
            this.canTouch = true;
            return;
        }
        if(!this.curSelectNode){
            this.curSelectNode = targetNode;
            let cs = this.curSelectNode.getComponent(level_cardComposition_cardGroup);
            cs.setMoveCardSelect(true);
        }else{
            let cs = this.curSelectNode.getComponent(level_cardComposition_cardGroup);
            let ts = targetNode.getComponent(level_cardComposition_cardGroup);
            if(targetNode.uuid == this.curSelectNode.uuid){
                cs.setMoveCardSelect(false);
                this.curSelectNode = null;
                this.canTouch = true;
                return;
            }
            // 判断能不能放入其他的节点 如果不能则当前选择节点跳到选择的节点
            let cMoveCards = cs.getMoveCards();
            let pushCardFlag:boolean = false;
            let cardOver:boolean = false;
            let moveCards:level_cardComposition_card[] = [];
            for(let i = 0 ; i <cMoveCards.length; i++){
                let card = cMoveCards[i];
                if(ts.checkCanPushCard(card)){
                    if(i == cMoveCards.length - 1){
                        cardOver = true;
                    }
                    pushCardFlag = true;
                    moveCards.push(card);
                    await new Promise<void>(resolve=>{
                        card.setSelect(false);
                        cs.spliceCard(card);
                        ts.pushCard(card);
                        this.scheduleOnce(resolve,0.05);
                    });
                }else{
                    break;
                }
            }
            // ts.pushCardEnd();
            for(let c of moveCards){
                c.onSpliceToGroup();
                c.onPushToGroup();
            }
            // cs.spliceCardEnd();
            cs.changeState();
            if(!pushCardFlag){
                // 没有移动卡牌 切换选择的卡牌
                cs.setMoveCardSelect(false);
                ts.setMoveCardSelect(true);
                this.curSelectNode = targetNode;
            }else{
                // if(!cs.getLastCard() || cardOver){
                    cs.setMoveCardSelect(false);
                    this.curSelectNode = null;
                // }
            }
        }
        this.canTouch = true;
    }

    /**
     * 创建指定点数的卡牌
     * @param cardComposition 点数
     * @param length 数量
     */
    async createAssignTypeCard(cardComposition:level_cardCompositionE,length:number,targetGroup:level_cardComposition_cardGroup){
        let cards = await this.createCardForCount(length,cardComposition,level_cardCompositionCardType.normal,targetGroup,false,false,false);
        // let cards:level_cardComposition_card[] = [];
        // for(let i = 0 ; i < length; i++){
        //     let card = this.getOneCard();
        //     let cs = card.getComponent(level_cardComposition_card);
        //     cards.push(cs);
        //     cs.bindData(cardComposition,level_cardCompositionCardType.normal);
        //     targetGroup.pushCard(cs,false,false);
        // }
        // targetGroup.pushCardEnd(cards);

        if(cardComposition == this.phaseTargetAry[this.phaseTargetAry.length - 1]){
            // 胜利
            let cardNode:cc.Node = cards[cards.length - 1].node;
            cardNode.zIndex = cc.macro.MAX_ZINDEX;
            //@ts-ignore
            cc.tween(cardNode).to(1,{position:cc.v2(0,0)}).call(()=>{
                this.coloured.active = true;
                this.Win(3);
            }).start();
        }
    }

    async createCards(isStart:boolean = false,hasAni:boolean = true,soundFlag:boolean = true){
        let canDealGroups = this.getCanDealCardGroup();
        canDealGroups = data_control.randomSortArray(canDealGroups);

        let fillCountAry:number[] = this.levelData["fill_num"].split("|").map((v)=>{
            return Number(v);
        })

        let dealCountAry:number[] = this.levelData["deal_num"].split("|").map((v)=>{
            return Number(v);
        });
        let dealCount = dealCountAry[canDealGroups.length - 1];
        let fillCount:number = fillCountAry[canDealGroups.length - 1];
        if(isStart){
            fillCount = 0;
        }
        let createCountAry:number[] = [];
        let maxCreateIndex:number = -1;
        let secondCreateIndex:number = -1;

        let maxCreate:number = 0;
        let secondCreate:number = 0;

        for(let i = 0; i < dealCount; i++){
            let maxCreateCount:number = Math.ceil((canDealGroups[i].getMaxCardsLength() - canDealGroups[i].getCurCardsLength()) / 2);
            maxCreateCount = Math.max(maxCreateCount,1);
            let minCreateNum:number = 1;
            let createCount:number = Math.ceil(data_control.getRandNumberOfArrayTwo([minCreateNum,maxCreateCount]));
            if(i < fillCount){
                createCount = canDealGroups[i].getMaxCardsLength() - canDealGroups[i].getCurCardsLength();
            }
            if(createCount > maxCreate){
                maxCreate = createCount;
                maxCreateIndex = i;
            }
            if(createCount > secondCreate && createCount <= maxCreate && i != maxCreateIndex){
                secondCreate = createCount;
                secondCreateIndex = i;
            }
            createCountAry.push(createCount);
        }
        let maxCutProAry:number[] = this.levelData["first_two_pro"].split("|").map(v=>{
            return Number(v);
        });

        let maxThreeCutProAry:number[] = this.levelData["first_three_pro"].split("|").map(v=>{
            return Number(v);
        });

        let secondCutProAry:number[] = this.levelData["second_cut_pro"].split("|").map(v=>{
            return Number(v);
        });

        let step = Math.max(this.curStep,0);
        let maxCutPro:number = maxCutProAry[step];
        let maxThreeCutPro:number = maxThreeCutProAry[step];
        let secondCutPro:number = secondCutProAry[step];
        let maxScore:number = Math.max(this.startCreateMaxCard,this.maxCardNum);
        let maxCardScore = Math.max(maxScore - 1,this.createMinCardNum);
        let minCardScore = this.createMinCardNum;
        let numAry:number[] = [];
        for(let i = minCardScore; i <= maxCardScore;i++){
            numAry.push(i);
        }
        let createCardScoreAry:number[] = [];
        let getOneCreateScore = ()=>{
            if(createCardScoreAry.length <= 0){
                createCardScoreAry = data_control.randomSortArray(numAry.concat());
            }
            return createCardScoreAry.pop();
        }

        let firstCutCountAry:number[] = [1,2,3];
        let seconCutCountAry:number[] = [1,2];
        let firstWeight:number[] = [1-maxCutPro-maxThreeCutPro,maxCutPro,maxThreeCutPro];
        let secondWeight:number[] = [1-secondCutPro,secondCutPro];

        let firstCutType:number = data_control.getRandIPosByWeights(firstWeight);        
        let secondCutType:number = data_control.getRandIPosByWeights(secondWeight);

        let firstCutCount:number =  createCountAry[maxCreateIndex] >= firstCutCountAry[firstCutType] ? firstCutCountAry[firstCutType] : createCountAry[maxCreateIndex];
        let secondCutCount:number =  createCountAry[secondCreateIndex] >= seconCutCountAry[secondCutType] ? seconCutCountAry[secondCutType] : createCountAry[secondCreateIndex];
        
        let allCutCount:number = dealCount + firstCutType + secondCutType;

        let secondMaxIndexAry:number[] = [];

        // if(allCutCount >= 4){
        //     // 有两段固定是当前第二大的值
        //     let randIndex:number = Math.floor(Math.random() * allCutCount);
        //     for(let i =0;i<2;i++){
        //         while(secondMaxIndexAry.includes(randIndex)){
        //             randIndex = Math.floor(Math.random() * allCutCount);
        //         }
        //         secondMaxIndexAry.push(randIndex);
        //     }
        // }

        let createCutCount:number = 0;

        let common_pro:number = Number(this.levelData["common_pro"]);
        let obstaclesPro:number = Number(this.levelData["obstacle_pro"]);
        let query_pro:number = Number(this.levelData["query_pro"]);

        let createTypeWeightAryByQuery:number[] = [1-common_pro-obstaclesPro-query_pro,common_pro,obstaclesPro,query_pro];

        let createTypeWeightAry:number[] = [1-common_pro-obstaclesPro,common_pro,obstaclesPro];

        for(let i = 0;i<dealCount;i++){
            let createCount:number = createCountAry[i];
            let group = canDealGroups[i];
            if(i == maxCreateIndex){
                let createCounts:number[] = new Array<number>(firstCutCount).fill(0);
                let queryFlag:boolean = false;
                if(createCounts.length > 1){
                    // 切两段以上
                    let type = data_control.getRandIPosByWeights(createTypeWeightAryByQuery);
                    if(type == 3){
                        queryFlag = true;
                    }
                }
                for(let j = 0;j<createCount;j++){
                    createCounts[j%firstCutCount] ++;
                }
                for(let j =0; j < createCounts.length; j++){
                    let curjCreateCount = createCounts[j];
                    let score:number = null;
                    if(j == 0 && queryFlag){
                        if(secondMaxIndexAry.includes(createCutCount)){
                            score = maxCardScore;
                        }else{
                            score = getOneCreateScore();
                        }
                        await this.createCardForCount(curjCreateCount,score,level_cardCompositionCardType.query,group,false,hasAni,soundFlag);
                    }else{
                        let type = data_control.getRandIPosByWeights(createTypeWeightAry);
                        switch(type){
                            case 0:{
                                if(secondMaxIndexAry.includes(createCutCount)){
                                    score = maxCardScore;
                                }else{
                                    score = getOneCreateScore();
                                }
                                await this.createCardForCount(curjCreateCount,score,level_cardCompositionCardType.normal,group,false,hasAni,soundFlag);
                                break;
                            }
                            case 1:{
                                await this.createCardForCount(curjCreateCount,null,level_cardCompositionCardType.universal,group,false,hasAni,soundFlag);
                                break;
                            }
                            case 2:{
                                await this.createCardForCount(curjCreateCount,null,level_cardCompositionCardType.obstacles,group,false,hasAni,soundFlag);
                                break;
                            }
                        }
                    }
                    createCutCount ++;
                }
            }else if(i == secondCreateIndex){
                let createCounts:number[] = new Array<number>(secondCutCount).fill(0);
                let queryFlag:boolean = false;
                if(createCounts.length > 1){
                    // 切两段以上
                    let type = data_control.getRandIPosByWeights(createTypeWeightAryByQuery);
                    if(type == 3){
                        queryFlag = true;
                    }
                }
                for(let j = 0;j<createCount;j++){
                    createCounts[ j % secondCutCount] ++;
                }
                for(let j = 0; j<createCounts.length; j++){
                    let curjCreateCount = createCounts[j];
                    let score:number = null;
                    if(j == 0 && queryFlag){
                        if(secondMaxIndexAry.includes(createCutCount)){
                            score = maxCardScore;
                        }else{
                            score = getOneCreateScore();
                        }
                        await this.createCardForCount(curjCreateCount,score,level_cardCompositionCardType.query,group,false,hasAni,soundFlag);
                    }else{
                        let type = data_control.getRandIPosByWeights(createTypeWeightAry);
                        switch(type){
                            case 0:{
                                if(secondMaxIndexAry.includes(createCutCount)){
                                    score = maxCardScore;
                                }else{
                                    score = getOneCreateScore();
                                }
                                await this.createCardForCount(curjCreateCount,score,level_cardCompositionCardType.normal,group,false,hasAni,soundFlag);
                                break;
                            }
                            case 1:{
                                await this.createCardForCount(curjCreateCount,null,level_cardCompositionCardType.universal,group,false,hasAni,soundFlag);
                                break;
                            }
                            case 2:{
                                await this.createCardForCount(curjCreateCount,null,level_cardCompositionCardType.obstacles,group,false,hasAni,soundFlag);
                                break;
                            }
                        }

                    }
                    createCutCount ++;
                }
            }else{
                let type = data_control.getRandIPosByWeights(createTypeWeightAry);
                let score:number = null;
                switch(type){
                    case 0:{
                        if(secondMaxIndexAry.includes(createCutCount)){
                            score = maxCardScore;
                        }else{
                            score = getOneCreateScore();
                        }
                        await this.createCardForCount(createCount,score,level_cardCompositionCardType.normal,group,false,hasAni,soundFlag);
                        break;
                    }
                    case 1:{
                        await this.createCardForCount(createCount,null,level_cardCompositionCardType.universal,group,false,hasAni,soundFlag);
                        break;
                    }
                    case 2:{
                        await this.createCardForCount(createCount,null,level_cardCompositionCardType.obstacles,group,false,hasAni,soundFlag);
                        break;
                    }
                }
                createCutCount ++;
            }
        }
        this.checkCanWashCard();
    }


    /** 创建卡牌 */
    async createCardForCount(createNum:number,cardScore:level_cardCompositionE,cardType:level_cardCompositionCardType,group:level_cardComposition_cardGroup,isJudge:boolean,hasAni:boolean = true,soundFlag:boolean = true){
        switch(cardType){
            case level_cardCompositionCardType.query:{
                this.introductionStack.push("1");
                break;
            }
            case level_cardCompositionCardType.universal:{
                this.introductionStack.push("0");
                break;
            }
        }
        this.openIntroduction();
        return new Promise<level_cardComposition_card[]>(async resolve=>{
            let cards:level_cardComposition_card[] = [];
            this.setMaxCard(cardScore);
            for(let k = 0; k<createNum; k++){
                await new Promise<void>(resolve1=>{
                    let card:cc.Node = this.getOneCard();
                    card.y = -750;
                    let cs = card.getComponent(level_cardComposition_card);
                    cards.push(cs);
                    cs.bindData(cardScore,cardType);
                    group.pushCard(cs,isJudge,hasAni,soundFlag).then(()=>{
                        resolve(cards);
                    });
                    // this.scheduleOnce(resolve1);
                    if(hasAni){
                        this.scheduleOnce(resolve1);
                    }else{
                        resolve1();
                    }
                });
            }
            group.pushCardEnd(cards);
        });
    }

    getCanDealCardGroup(leisureNum:number = 1){
        let groupAry:level_cardComposition_cardGroup[] = [];
        this.groupContent.children.forEach((group:cc.Node)=>{
            let gs = group.getComponent(level_cardComposition_cardGroup);
            if(!gs.lockFlag && gs.groupType != level_cardCompositionGroupTypeE.temp && gs.getMaxCardsLength() - gs.getCurCardsLength() >= leisureNum){
                groupAry.push(gs);
            }
        });
        return groupAry;
    }

    onBtnSynthesis(){
        if(!this.canTouch){
            return;
        }
        this.canTouch = false;
        O1HD.getManagers().soundMgr.playSound("cardComposition/click");
        let trueFlag:boolean = false;
        this.groupContent.children.forEach((group:cc.Node)=>{
            let gs = group.getComponent(level_cardComposition_cardGroup);
            let nextType = gs?.getLastCard()?.cardComposition + 1;
            let soundFlag:boolean = false;
            if(gs.checkCanSynthesis()){
                trueFlag = true;
                let fun = (isTrue:boolean)=>{
                    if(isTrue){
                        if(!soundFlag){
                            soundFlag = true;
                            O1HD.getManagers().soundMgr.playSound("cardComposition/HeCheng");
                        }
                        if(this.curSelectNode &&  this.curSelectNode.uuid == group.uuid){
                            this.curSelectNode = null;
                        }
                       this.createAssignTypeCard(nextType,2,gs).then(()=>{
                            if(gs.groupType == level_cardCompositionGroupTypeE.temp){
                                gs.checkTempGroupToBack();
                            }
                            this.canTouch = true;
                            this.checkCanWashCard();
                       });
                    }
                }
                gs.cardSynthesis().then(fun);
            }
        });
        if(!trueFlag){
            this.canTouch = true;
        }
    }

    getOneCard(){
        if(this.cardPool.size() > 0){
            let node = this.cardPool.get();
            let ns = node.getComponent(level_cardComposition_card);
            ns.initCard(this);
            return node;
        }
        let node:cc.Node = cc.instantiate(this.cardP);
        let ns = node.getComponent(level_cardComposition_card);
        ns.initCard(this);
        return node;
    }

    putOneCard(cardNode:cc.Node){
        this.cardPool.put(cardNode);
    }

    /**
     * 放置一张卡牌的动画
     * @param targetNode 目标节点
     * @param worldPos 世界坐标
     */
    pushCardAni(targetNode:cc.Node,worldPos:cc.Vec2,hasAni:boolean,soundFlag:boolean = true){
        return new Promise<void>(resolve=>{
            targetNode.setParent(this.cardContent);
            targetNode.zIndex = 1000;
            let needTime:number = 0.2;
            let targetPos:cc.Vec2 = this.cardContent.convertToNodeSpaceAR(worldPos);
            if(soundFlag){
                O1HD.getManagers().soundMgr.playSound("cardComposition/YiDong1");
            }
            if(hasAni){
                //@ts-ignore
                cc.tween(targetNode).to(needTime,{position:targetPos}).call(()=>{
                    resolve();
                }).start();
            }else{
                targetNode.setPosition(targetPos);
                resolve();
            }
        });
    }

    async onBtnDealCard(){
        O1HD.getManagers().soundMgr.playSound("cardComposition/click");
        if(!this.canTouch){
            return;
        }
        this.canTouch = false;
        await this.createCards(false,true);
        this.canTouch = true;
    }

    setMaxCard(max:number){
        if(max > this.maxCardNum){
            this.maxCardNum = max;
            let phase:number = -1;
            for(let i = 0; i< this.phaseTargetAry.length; i++){
                let phaseTarget:number = this.phaseTargetAry[i];
                if(this.maxCardNum == phaseTarget){
                    phase = i;
                }
            }
            if(phase > this.curStep){
                this.curStep = phase;
                this.changeStep();
                // 切换了一个阶段
            }
        }
    }

    /**
     * 更改step
     */
    changeStep(){
        let step = this.curStep;
        let unlockGroup:level_cardComposition_cardGroup = this.needUnlockGroupAry[step];
        unlockGroup?.setCanUnlock();
    }

    getRandLeisureGroup(){
        let groups = this.getCanDealCardGroup(2);
        if(groups.length > 0){
            let randGroup = data_control.getRandItemOfArray(groups);
            return randGroup;
        }
        return null;
    }

    /* 判断是否可以洗牌  */
    checkCanWashCard(){
        let dealCount:number = 0;
        let groups = this.getCanDealCardGroup(0);
        let maxLength:number = 0;
        groups.forEach((gs:level_cardComposition_cardGroup)=>{
            let canDealCount = gs.getCurCardsLength();
            dealCount += canDealCount;
            maxLength += gs.getMaxCardsLength();
        });
        let ratio:number = Number(this.levelData["wash_card_ratio"]) || 0.8;
        // console.log(dealCount,maxLength,dealCount/maxLength,ratio);
        if(dealCount / maxLength >= ratio){
            this.inGamePage.showWashCard(true);
        }else{
            this.inGamePage.showWashCard(false);
        }
    }

    washCard(){
        if(!this.canTouch){
            return;
        }
        this.canTouch = false;
        this.inGamePage.showWashCard(false);
        let minCard:number = level_cardCompositionE.LENGTH;
        let maxCard:number = 0;
        O1HD.getManagers().soundMgr.playSound("cardComposition/XiPai");
        let cards:level_cardComposition_card[][] = [];
        let universalAry:level_cardComposition_card[] = [];
        let obstaclesAry:level_cardComposition_card[] = [];

        this.groupContent.children.forEach((group:cc.Node)=>{
            let gs = group.getComponent(level_cardComposition_cardGroup);
            let gCards:level_cardComposition_card[] = gs.getCards();
            for(let i = 0; i < gCards.length; i++){
                let card = gCards[i];
                card.setSelect(false);
                let composition = card.cardComposition;
                if(!cards[composition]){
                    cards[composition] = [];
                }
                switch(card.cardType){
                    case level_cardCompositionCardType.normal:{
                        cards[composition].push(card);
                        minCard = Math.min(composition,minCard);
                        maxCard = Math.max(composition,maxCard);
                        break;
                    }
                    case level_cardCompositionCardType.universal:{
                        universalAry.push(card);
                        card.onSpliceToGroup();
                        break;
                    }
                    case level_cardCompositionCardType.query:{
                        // 卡牌翻开
                        card.cardToflip();
                        cards[composition].push(card);
                        minCard = Math.min(composition,minCard);
                        maxCard = Math.max(composition,maxCard);
                        break;
                    }
                    case level_cardCompositionCardType.obstacles:{
                        obstaclesAry.push(card);
                        break;
                    }
                }
            }
            gs.spliceAllCards();
        });
        let oneCard:level_cardComposition_card[] = [];
        let canDealCardGroup = this.getCanDealCardGroup(0);
        for(let i = canDealCardGroup.length - 1;i >=0; i--){
            let group = canDealCardGroup[i];
            let composition = i + this.createMinCardNum;
            let ary:level_cardComposition_card[] = cards[composition] || [];
            for(let i = 0; i <ary.length; i++){
                let card = ary[i];
                ary[i] = null;
                oneCard.push(card);
                if(group.getCurCardsLength() < group.getMaxCardsLength()){
                    group.pushCard(card,false,true,false).then(()=>{
                        this.canTouch = true;
                    });
                }else{
                    ary[i] = null;
                    this.putOneCard(card.node);
                }
            }
            group.pushCardEnd(oneCard);
        }

        for(let i = 0;i<cards.length;i++){
            for(let j = 0;j<cards[i]?.length;j++){
                let c = cards[i][j];
                if(c){
                    this.putOneCard(c.node);
                }
            }
        }

        for(let i = 0;i<obstaclesAry.length;i++){
            let card = obstaclesAry[i];
            this.putOneCard(card.node);
        }

        for(let i = 0;i<universalAry.length;i++){
            let card = universalAry[i];
            this.putOneCard(card.node);
        }

        // let canDealCardGroup2 = this.getCanDealCardGroup(1);
        // for(let i = 0;i<canDealCardGroup2.length;i++){
        //     let group = canDealCardGroup2[i];
        //     let twoCards:level_cardComposition_card[] = [];
        //     while(universalAry.length > 0 && group.getMaxCardsLength() - group.getCurCardsLength() > 0){
        //         let card = universalAry.pop();
        //         twoCards.push(card);
        //         group.pushCard(card,false,true);
        //     }
        //     group.pushCardEnd(twoCards);
        // }
    }

    /**打开介绍界面 */
    async openIntroduction(){
        if(this.introductionStack.length <= 0){
            return;
        }
        if(this.openIntroductionFlag){
            return;
        }
        let type = this.introductionStack.shift();
        if(this._introductionAry.includes(type)){
            this.openIntroduction();
            return;
        }
        this._introductionAry.push(type);
        this.writeData();
        this.openIntroductionFlag = true;
        let page = await mainRoot.UISystem.OpenPage(PAGE.CARD_INTRODUCTION);
        let p = page as CardIntroductionPage;
        p.bindType(type,()=>{
            this.openIntroductionFlag = false;
            this.openIntroduction();
        });
    }

}
